// 指令格式
class InstructionFormat {
  // 版本号下标
  static _version = 4
  static _send = 5
  static _receive = 6

  // 数据链路码下标
  static _data_chain_code = 7

  static _region = 8

  // 信号机编号下标
  static _cross_number = 12
  // 操作类型下标
  static _operate_type = 13
  // 对象标志下标
  static _object_id = 14
  // 流水号下标
  static _serial_number = 18
}

class ObjectIdFlag {
  // 联机请求对象标志
  static _heart = 1
  // 相位对象标志
  static _phase = 51
  // 灯组对象标志
  static _lame = 52
  // 安保对象标志
  static _security = 53
}

// 版本号 4 [4]
const takeVersion = (res) => {
  return res[InstructionFormat._version]
}

const takeSend = (res) => { return res[InstructionFormat._send] }

const takeReceive = (res) => { return res[InstructionFormat._receive] }

// 数据链路码 7 [7]
const takeDataChainCode = (res) => {
  return res[InstructionFormat._data_chain_code]
}

const takeRegion = (res) => { return res[InstructionFormat._region] }

// 路口编号 12 [9,13]
const takeCrossNumber = (res) => {
  let a = res.slice(
    InstructionFormat._cross_number - 3,
    InstructionFormat._cross_number + 1
  )
  return takeByteArray2int(a)
}

// 操作类型 13 [13]
const takeOperateType = (res) => {
  return res[InstructionFormat._operate_type]
}

// 对象标识 14 [14]
const takeObjectId = (res) => {
  return res[InstructionFormat._object_id]
}

// 流水号 18 [15,19]
const takeSerialNumber = (res) => {
  let a = res.slice(
    InstructionFormat._serial_number - 3,
    InstructionFormat._serial_number + 1
  )
  return takeByteArray2int(a)
}

const takeObjectNumber = (res) => 0x00


// byte[] 转 int,小端模式
const takeByteArray2int = (b) => {
  let arr = [...b]
  arr.reverse()
  let total = arr.reduce((previousVal, currentVal, currentIndex, array) => {
    let a = currentVal.toString(16)
    if (a.length === 1) {
      a = "0" + currentVal.toString(16)
    }
    return (previousVal += a)
  }, "")
  return parseInt(total, 16)
}

// int[] 转 2进制
const takeIntArray2binary = (arr) => {
  return arr.reduce((pre, val, index, origin) => {
    let b = val.toString(2)
    let c = 8 - b.length
    let d = ""
    if (c > 0) {
      for (let i = 0; i < c; i++) {
        d += "0"
      }
    }
    let e = d + b
    return (pre += e)
  }, "0b")
}

const protocal_head = [0xfa, 0xfb, 0xfc, 0xfd]

export {
  takeVersion,
  takeSend,
  takeReceive,
  takeDataChainCode,
  takeRegion,
  takeCrossNumber,
  takeOperateType,
  takeObjectId,
  takeSerialNumber,
  takeObjectNumber,
  takeByteArray2int,
  protocal_head,
  ObjectIdFlag
}
